import * as vscode from 'vscode';
import Parser = require('tree-sitter');
import { LanguageManager } from './languageManager';
import { ASTHelper } from './astHelper';
import { ErrorClassifier, ErrorType } from './errorClassifier';
import { LSPSuggester, LSPSuggestion } from './lspSuggester';
import { TextHelper } from './textHelper';
import { ContextAnalyzer } from './contextAnalyzer';
import { sendLSPErrorToLLM } from './llmAnalysisFunctions'
export class ErrorAnalyzer {
  constructor(private languageManager: LanguageManager) {}

  async analyzeDiagnostics(event: vscode.DiagnosticChangeEvent): Promise<void> {
    for (const uri of event.uris) {
      await this.analyzeDocumentDiagnostics(uri);
    }
  }

  // 新增：分析当前光标位置的上下文（当没有错误时调用）
  async analyzeCurrentContext(uri: vscode.Uri, position: vscode.Position): Promise<void> {
    const doc = vscode.workspace.textDocuments.find(d => d.uri.toString() === uri.toString());
    if (!doc) return;

    const langId = doc.languageId;
    if (!this.languageManager.isSupported(langId)) {
      return;
    }

    const parser = this.languageManager.getParser(langId);
    if (!parser) return;

    // 解析整个文档的AST
    const tree = parser.parse(doc.getText());
    
    // 分析当前位置的上下文
    const cursorPosition = {
      row: position.line,
      column: position.character
    };

    const context = ContextAnalyzer.analyzeCurrentContext(tree, cursorPosition, doc);
    
    // 格式化输出上下文信息
    await ContextAnalyzer.formatContextInfo(context, doc, position);
  }

  // 新增：检查文档是否有错误
  hasErrors(uri: vscode.Uri): boolean {
    const diagnostics = vscode.languages.getDiagnostics(uri);
    return diagnostics.length > 0;
  }

// 在errorAnalyzer.ts中修改smartAnalyze方法
async smartAnalyze(uri: vscode.Uri, position?: vscode.Position): Promise<void> {
    
    const doc = vscode.workspace.textDocuments.find(d => d.uri.toString() === uri.toString());
    if (!doc || !position) {
        return;
    }


    // 检查语言支持
    const langId = doc.languageId;
    
    if (!this.languageManager.isSupported(langId)) {
        return;
    }

    const parser = this.languageManager.getParser(langId);
    if (!parser) {
        return;
    }

    try {
        const tree = parser.parse(doc.getText());
        
        const cursorPosition = {
            row: position.line,
            column: position.character
        };

        const context = ContextAnalyzer.analyzeCurrentContext(tree, cursorPosition, doc);
        
        await ContextAnalyzer.formatContextInfo(context, doc, position);
    } catch (error) {
        throw error;
    }
}

  private async analyzeDocumentDiagnostics(uri: vscode.Uri): Promise<void> {
    const diagnostics = vscode.languages.getDiagnostics(uri);
    const doc = vscode.workspace.textDocuments.find(d => d.uri.toString() === uri.toString());

    if (!doc || diagnostics.length === 0) return;

    const langId = doc.languageId;
    if (!this.languageManager.isSupported(langId)) return;

    const parser = this.languageManager.getParser(langId);
    if (!parser) return;

    // 解析整个文档的AST
    const tree = parser.parse(doc.getText());

    // 按优先级排序诊断信息
    const sortedDiagnostics = this.sortDiagnosticsByPriority(diagnostics);

    // 处理每个错误（限制处理数量以避免输出过多）
    const maxErrors = 1;
    for (let i = 0; i < Math.min(sortedDiagnostics.length, maxErrors); i++) {
      const diagnostic = sortedDiagnostics[i];
      await this.analyzeSingleError(doc, tree, diagnostic);
    }

    if (sortedDiagnostics.length > maxErrors) {
      console.log(`\n注意: 还有 ${sortedDiagnostics.length - maxErrors} 个错误未显示详细信息\n`);
    }
  }

  private sortDiagnosticsByPriority(diagnostics: vscode.Diagnostic[]): vscode.Diagnostic[] {
    return diagnostics
      .map(diagnostic => ({
        diagnostic,
        classification: ErrorClassifier.classify(diagnostic)
      }))
      .sort((a, b) => a.classification.priority - b.classification.priority)
      .map(item => item.diagnostic);
  }

  private async analyzeSingleError(
    doc: vscode.TextDocument,
    tree: Parser.Tree,
    diagnostic: vscode.Diagnostic
  ): Promise<void> {
    const errorPosition = {
      row: diagnostic.range.start.line,
      column: diagnostic.range.start.character
    };

    // 分类错误
    const classification = ErrorClassifier.classify(diagnostic);

    // 找到错误位置对应的AST节点
    const errorNode = ASTHelper.findNodeAtPosition(tree.rootNode, errorPosition);
    const semanticNode = errorNode ? ASTHelper.findSemanticNode(tree.rootNode, errorPosition) : null;

    if (errorNode && semanticNode) {
      await this.logErrorWithContext(diagnostic, doc, errorNode, semanticNode, classification);
    }
  }

  private async logErrorWithContext(
    diagnostic: vscode.Diagnostic,
    doc: vscode.TextDocument,
    errorNode: Parser.SyntaxNode,
    semanticNode: Parser.SyntaxNode,
    classification: { type: ErrorType; category: string; priority: number; needsLSPSuggestion: boolean }
  ): Promise<void> {
    const errorLine = diagnostic.range.start.line;
    const errorColumn = diagnostic.range.start.character;
    const errorPosition = new vscode.Position(errorLine, errorColumn);

    console.log('\n========== LSP 错误分析 ==========');
    console.log(`错误类型: ${classification.category} (优先级: ${classification.priority})`);
    console.log(`错误消息: ${diagnostic.message}`);
    console.log(`文件位置: ${doc.uri.fsPath}:${errorLine + 1}:${errorColumn + 1}`);

    console.log('\n--- AST 节点信息 ---');
    console.log(`精确节点类型: ${errorNode.type}`);
    console.log(`精确节点内容: ${TextHelper.truncate(errorNode.text, 100)}`);
    console.log(`语义节点类型: ${semanticNode.type}`);
    console.log(`语义节点内容: ${TextHelper.truncate(semanticNode.text, 200)}`);

    // 显示父节点信息
    if (semanticNode.parent) {
      console.log(`父节点类型: ${semanticNode.parent.type}`);
      console.log(`父节点内容: ${TextHelper.truncate(semanticNode.parent.text, 300)}`);
    }

    console.log('\n--- 代码上下文 ---');
    const contextLines = TextHelper.getCodeContext(doc, errorLine, 2);
    contextLines.forEach(line => console.log(line));

    // 获取LSP建议
    if (classification.needsLSPSuggestion) {
      console.log('\n--- LSP 智能建议 ---');
      await this.displayLSPSuggestions(doc, errorPosition, semanticNode, diagnostic, classification.type);
    }

    // 如果在displayLSPSuggestions方法中获得了suggestions
    const lspSuggestions = await LSPSuggester.getSuggestions(doc, errorPosition, semanticNode, diagnostic, classification.type);
    await sendLSPErrorToLLM(diagnostic, doc, errorNode, semanticNode, classification, lspSuggestions);
  }

  private async displayLSPSuggestions(
    doc: vscode.TextDocument,
    position: vscode.Position,
    errorNode: Parser.SyntaxNode,
    diagnostic: vscode.Diagnostic,
    errorType: ErrorType
  ): Promise<void> {
    try {
      const suggestions = await LSPSuggester.getSuggestions(
        doc,
        position,
        errorNode,
        diagnostic,
        errorType
      );

      // 显示不同类型的建议
      if (suggestions.functionInfo && TextHelper.hasUsefulContent(suggestions.functionInfo)) {
        console.log(`函数定义信息:`);
        console.log(`  ${suggestions.functionInfo}`);
      }

      if (suggestions.hoverInfo && TextHelper.hasUsefulContent(suggestions.hoverInfo)) {
        console.log(`类型信息:`);
        console.log(`  ${suggestions.hoverInfo}`);
      }

      if (suggestions.signatures && suggestions.signatures.length > 0) {
        console.log(`正确的函数签名:`);
        suggestions.signatures.forEach((sig, index) => {
          console.log(`  ${index + 1}. ${sig}`);
        });
      }

      if (suggestions.codeActions && suggestions.codeActions.length > 0) {
        console.log(`修复建议:`);
        suggestions.codeActions.forEach((action, index) => {
          console.log(`  ${index + 1}. ${action}`);
        });
      }

      if (suggestions.completions && suggestions.completions.length > 0) {
        const label = errorType === ErrorType.ATTRIBUTE_ERROR || errorType === ErrorType.SPELLING_ERROR
          ? '可能的正确拼写:'
          : '可能的正确选项:';
        console.log(label);
        suggestions.completions.forEach((completion, index) => {
          console.log(`  ${index + 1}. ${completion}`);
        });
      }

      // 如果没有获取到任何有用的建议
      const hasAnyUsefulSuggestion = [
        suggestions.functionInfo,
        suggestions.hoverInfo
      ].some(s => s && TextHelper.hasUsefulContent(s)) ||
        [suggestions.signatures, suggestions.codeActions, suggestions.completions].some(arr => arr && arr.length > 0);

      if (!hasAnyUsefulSuggestion) {
        console.log('暂无可用的智能建议');
      }

    } catch (error) {
      console.log(`获取LSP建议时出错: ${error}`);
    }
  }
}